import {getGuid} from "./guid";
import UNI_APP from "../.env";
// import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'; // import before mqtt.
// import 'esbuild-plugin-polyfill-node/polyfills/navigator'
import mqtt from "mqtt";
// import mqtt from 'mqtt' //引入mqtt

let wsurl = "";
let accessToken = "";
let messageCallBack = null;
let closeCallBack = null;
let connectCallBack = null;
let isConnect = false; //连接标识 避免重复连接
let rec = null;
let isInit = false;
let lastConnectTime = new Date(); // 最后一次连接时间

let init = () => {
	// 防止重复初始化
	if (isInit) {
		return;
	}
	isInit = true;
	uni.onSocketOpen((res) => {
		console.log("WebSocket连接已打开");
		isConnect = true;
		// 发送登录命令
		let loginInfo = {
			cmd: 0,
			data: {
				accessToken: accessToken
			}
		};
		uni.sendSocketMessage({
			data: JSON.stringify(loginInfo)
		});
	})

	uni.onSocketMessage((res) => {
		let sendInfo = JSON.parse(res.data)
		if (sendInfo.cmd == 0) {
			heartCheck.start()
			connectCallBack && connectCallBack();
			console.log('WebSocket登录成功')
		} else if (sendInfo.cmd == 1) {
			// 重新开启心跳定时
			heartCheck.reset();
		} else {
			// 其他消息转发出去
			console.log("接收到消息", sendInfo);
			messageCallBack && messageCallBack(sendInfo.cmd, sendInfo.data)
		}
	})

	uni.onSocketClose((res) => {
		console.log('WebSocket连接关闭')
		isConnect = false;
		closeCallBack && closeCallBack(res);
	})

	uni.onSocketError((e) => {
		console.log(e)
		isConnect = false;
		// APP 应用切出超过一定时间(约1分钟)会触发报错，此处回调给应用进行重连
		closeCallBack && closeCallBack({code: 1006});
	})
};

let connect = (url, token) => {
	wsurl = url;
	accessToken = token;
	if (isConnect) {
		return;
	}
	lastConnectTime = new Date();
	uni.connectSocket({
		url: wsurl,
		success: (res) => {
			console.log("websocket连接成功");
		},
		fail: (e) => {
			console.log(e);
			console.log("websocket连接失败，10s后重连");
			setTimeout(() => {
				connect();
			}, 10000)
		}
	});
}

//定义重连函数
let reconnect = (wsurl, accessToken) => {
	console.log("尝试重新连接");
	if (isConnect) {
		//如果已经连上就不在重连了
		return;
	}
	// 延迟10秒重连  避免过多次过频繁请求重连
	let timeDiff = new Date().getTime() - lastConnectTime.getTime()
	let delay = timeDiff < 10000 ? 10000 - timeDiff : 0;
	rec && clearTimeout(rec);
	rec = setTimeout(function() {
		connect(wsurl, accessToken);
	}, delay);
};

//设置关闭连接
let close = (code) => {
	if (!isConnect) {
		return;
	}
	uni.closeSocket({
		code: code,
		complete: (res) => {
			console.log("关闭websocket连接");
			isConnect = false;
		},
		fail: (e) => {
			console.log("关闭websocket连接失败", e);
		}
	});
};


//心跳设置
var heartCheck = {
	timeout: 10000, //每段时间发送一次心跳包 这里设置为30s
	timeoutObj: null, //延时发送消息对象（启动心跳新建这个对象，收到消息后重置对象）
	start: function() {
		if (isConnect) {
			console.log('发送WebSocket心跳')
			let heartBeat = {
				cmd: 1,
				data: {}
			};
			uni.sendSocketMessage({
				data: JSON.stringify(heartBeat),
				fail(res) {
					console.log(res);
				}
			})
		}
	},
	reset: function() {
		clearTimeout(this.timeoutObj);
		this.timeoutObj = setTimeout(function() {
			heartCheck.start();
		}, this.timeout);
	}

}

// 实际调用的方法
function sendMessage(agentData) {
	uni.sendSocketMessage({
		data: agentData
	})
}

let onConnect = (callback) => {
	connectCallBack = callback;
}


function onMessage(callback) {
	messageCallBack = callback;
}


function onClose(callback) {
	closeCallBack = callback;
}

let client
let publishTopic = '/000001'  //发布Topic
let userId = null;
let groupIds = null;
let allTopic = [];
let MQTT_IP_ADDRESS = 'mqtt://127.0.0.1:1883' //mqtt地址端口
let MQTT_WS_ADDRESS = UNI_APP.WS_URL //mqtt ws 地址端口

if (!MQTT_WS_ADDRESS) {
	MQTT_WS_ADDRESS = "mqtt://127.0.0.1:8083";
}
let MQTT_OPTIONS = {
	connectTimeout: 5000,                              // 连接超时时间
	//clientId: getGuid() + '_user_' + userId,  // clientId不能重复，这里可以随机生成
	username: 'test',                                  // 用户名
	password: 'test',                                  // 密码
	clean: true,                                       // 清理session
	keepalive: 60,                                     // 设置心跳间隔为60秒: false
	timerVariant: 'native'                             // more info ref issue: #1797

}
export function setUserId(id) {
	userId = id;
}

export function setGroupIds(groups) {
	groupIds = groups.map(group => group.id);
}
//创建客户端连接
export function initMqtt() {
	console.log("开始连接WebSocket initMqtt")

	this.connectMqtt("mqtt连接成功");
	this.messageMqtt();
	setInterval(reconnectMqtt, 5000)
	// 测试消息
	// this.mqttPublish("1234")
}
export function connectMqtt(msg) {
	MQTT_OPTIONS.clientId = getGuid() + '_user_' + userId;
	client = mqtt.connect(MQTT_WS_ADDRESS, MQTT_OPTIONS, function (err) {
		console.log(err)
	})
	client.on('connect', function () {
		console.log(msg)
		isConnect = true
	})
}
// 重连
export function reconnectMqtt() {
	if (userId && !isConnect) {
		connectMqtt("mqtt重连成功");
	}
}

// //接收消息
export function messageMqtt() {
	// 我的topic
	let userTopic = "/user/message/" + userId;
	// 添加群消息topic前缀
	let prefix = '/group/message/';
	// 群topic
	allTopic = groupIds.map(item => prefix + item);
	client.on('connect', function () {
		console.log('Connected')
		// 订阅群消息主题
		for (var i = 0; i < allTopic.length; i++) {
			console.log("订阅第" + i + "个主题,topic:" + allTopic[i]);
			let topic = allTopic[i];
			client.subscribe(topic, function (err) {
				console.log("err" + err)
				// if (!err) {
				//     // 给服务器发布消息
				//     client.publish('000001', 'Hello mqtt')
				// }
			})
		}
		// 订阅用户私聊消息主题
		client.subscribe(userTopic, function (err) {
			console.log("err" + err)
			// if (!err) {
			//     // 给服务器发布消息
			//     client.publish('000001', 'Hello mqtt')
			// }
		})
	})

	// 接收消息
	client.on('message', function (topic, message) {
		// message is Buffer
		// 接收消息
		let decoder = new TextDecoder("utf-8");
		// Using decode method to get string output
		let str = decoder.decode(message);
		// let data = JSON.parse(str);
		// let cmd = data.cmd;
		// console.log("收到消息 message: " + data)
		// switch (cmd) {
		// 	case CMD_TYPE.PRIVATE_MESSAGE:
		// 		// getApp().handlePrivateMessage(data.data);
		// 		break;
		// 	case CMD_TYPE.GROUP_MESSAGE:
		// 		// getApp().handleGroupMessage(data.data);
		// 		break;
		// 	default:
		// 		//与 case 1 和 case 2 不同时执行的代码
		// 		break
		// }
		console.log('收到消息:',str)
		let sendInfo = JSON.parse(str);

		if (sendInfo.cmd == 0) {
			heartCheck.start()
			// 登录成功才算真正完成连接
			connectCallBack && connectCallBack();
			console.log('WebSocket登录成功')
		} else if (sendInfo.cmd == 1) {
			// 重新开启心跳定时
			heartCheck.reset();
		} else {
			// 其他消息转发出去
			console.log("收到消息:",sendInfo);
			messageCallBack && messageCallBack(sendInfo.cmd, sendInfo.data)
		}
		// client.end()
	})
}
export function mqttPublish(msg) {
	if (isConnect) {
		// if(mqttConnected){
		client.publish(publishTopic, msg, {qos: 1, retain: false});//hello mqtt +
		console.log('发布了一条消息', msg)
	} else {
		console.log("MQTT服务器未连接!")

		// uni.showToast({
		//     title: 'MQTT服务器未连接',
		//     icon: 'none'
		// });
	}
}

//断开连接
export function mqttDisconnect() {
	console.log('mqttConnected', isConnect)
	if (isConnect) {
		client.end(true)
		isConnect = false
	}
}


// 将方法暴露出去
export {
	init,
	connect,
	reconnect,
	close,
	sendMessage,
	onConnect,
	onMessage,
	onClose
}